package city.spring.modules.cardinfo.service.impl;

import city.spring.domain.enums.CardExpenseRecordType;
import city.spring.modules.bed.service.BedManagementService;
import city.spring.modules.cardinfo.entity.CardExpenseRecordEntity;
import city.spring.modules.cardinfo.entity.CardNumberEntity;
import city.spring.modules.cardinfo.repository.CardExpenseRecordRepository;
import city.spring.modules.cardinfo.service.CardExpenseRecordService;
import city.spring.modules.cardinfo.service.CardNumberService;
import city.spring.modules.consumptionItem.service.ConsumptionItemsService;
import city.spring.modules.oldman.service.OldmanInfoService;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

/**
 * Service：消费记录
 *
 * @author Panxm
 * @date 2020-04-13 16:01:41
 */
@CacheConfig(cacheNames = {CardExpenseRecordServiceImpl.CACHE_NAME})
@Transactional(rollbackFor = Throwable.class)
@Service
public class CardExpenseRecordServiceImpl extends ServiceImpl<CardExpenseRecordRepository, CardExpenseRecordEntity> implements CardExpenseRecordService {

    private final CardNumberService cardNumberService;
    private final ConsumptionItemsService consumptionItemsService;
    private final OldmanInfoService oldmanInfoService;
    private final BedManagementService bedManagementService;

    public CardExpenseRecordServiceImpl(CardNumberService cardNumberService, ConsumptionItemsService consumptionItemsService, OldmanInfoService oldmanInfoService, BedManagementService bedManagementService) {
        this.cardNumberService = cardNumberService;
        this.consumptionItemsService = consumptionItemsService;
        this.oldmanInfoService = oldmanInfoService;
        this.bedManagementService = bedManagementService;
    }

    @Override
    public void saveCardExpenseRecord(CardExpenseRecordEntity cardExpenseRecordEntity, CardNumberEntity cardNumberEntity) {
        int random = (int) (Math.random() * 9 + 1);
        String valueOf = String.valueOf(random);
        int hashCode = UUID.randomUUID().toString().hashCode();
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        String value = valueOf + String.format("%015d", hashCode);
        cardExpenseRecordEntity.setNo(value);
        cardNumberEntity.setLastConsumption(cardExpenseRecordEntity.getNo());
        BigDecimal expenseAmount = cardExpenseRecordEntity.getNumber().multiply(consumptionItemsService.getById(cardExpenseRecordEntity.getPayServiceId()).getCost());
        cardExpenseRecordEntity.setAmount(expenseAmount);
        boolean save = save(cardExpenseRecordEntity);
        boolean update = cardNumberService.updateById(cardNumberEntity);
        if (!save || !update) {
            throw new RuntimeException("保存信息失败");
        }
    }

    @Override
    public void updateCardExpenseRecord(CardExpenseRecordEntity entity) {
        // 使用 updateById(entity); 修改数据时，将会修改 entity 对象中所有非null数据，如果某个字段为null，将会忽略该字段的修改
        boolean update = updateById(entity);
        if (!update) {
            throw new RuntimeException("修改信息失败");
        }
    }

    @Override
    public void deleteCardExpenseRecord(String primaryKey) {
        removeById(primaryKey);
    }

    @Override
    public void deleteCardExpenseRecord(List<String> primaryKeys) {
        removeByIds(primaryKeys);
    }

    @Override
    public void saveCardExpenseRecord(CardExpenseRecordEntity cardExpenseRecordEntity) {
        save(cardExpenseRecordEntity);
    }

    @Override
    public void chargeMoneyByCardId(String cardNumberId, BigDecimal amount) {
        CardNumberEntity cardNumber = cardNumberService.getById(cardNumberId);
        chargeMoney(cardNumber, amount);
    }

    @Override
    public void chargeMoneyByMemberNumber(String memberNumber, BigDecimal amount) {
        CardNumberEntity cardNumber = cardNumberService.getCardNumber(memberNumber);
        chargeMoney(cardNumber, amount);
    }

    /**
     * 会员卡余额充值
     *
     * @param cardNumber 会员卡对象
     * @param amount     充值金额
     */
    private void chargeMoney(CardNumberEntity cardNumber, BigDecimal amount) {
        if (cardNumber == null) {
            throw new RuntimeException("未找到会员卡");
        }
        CardExpenseRecordEntity recordEntity = buildCardExpenseRecordEntity(cardNumber, amount);

//        recordEntity.setType("充值");
//        recordEntity.setName("余额充值");
//        recordEntity.setFlowType(false);

        save(recordEntity);
        cardNumberService.updateById(cardNumber);
    }

    /**
     * 通过消费金额和会员卡信息生成基础消费记录信息
     *
     * @param cardNumber 会员卡信息
     * @param amount     消费金额，充值为正数，消费为负数
     * @return 消费记录信息
     */
    private CardExpenseRecordEntity buildCardExpenseRecordEntity(CardNumberEntity cardNumber, BigDecimal amount) {
        CardExpenseRecordEntity recordEntity = new CardExpenseRecordEntity();
        recordEntity.setPersonName(cardNumber.getPersonName());
        recordEntity.setMemberCard(cardNumber.getMemberCard());

        recordEntity.setAmount(amount);
        cardNumber.setBalance(cardNumber.getBalance().add(amount));
        recordEntity.setBalance(cardNumber.getBalance());
        recordEntity.setNo(IdWorker.getIdStr());

        // 记录上次消费ID
        cardNumber.setLastConsumption(recordEntity.getNo());

        return recordEntity;
    }

    @Override
    public void consumptionByCardId(String cardNumberId, BigDecimal amount, CardExpenseRecordType type, String remarks) {
        CardNumberEntity cardNumber = cardNumberService.getById(cardNumberId);
        consumption(cardNumber, amount, type, remarks);
    }

    @Override
    public void consumptionByMemberNumber(String memberNumber, BigDecimal amount, CardExpenseRecordType type, String remarks) {
        CardNumberEntity cardNumber = cardNumberService.getCardNumber(memberNumber);
        consumption(cardNumber, amount, type, remarks);
    }

    /**
     * 一卡通消费
     *
     * @param cardNumber 一卡通实体对象
     * @param amount     消费金额
     * @param type       消费类型
     * @param remarks    消费说明（标题信息）
     */
    private void consumption(CardNumberEntity cardNumber, BigDecimal amount, CardExpenseRecordType type, String remarks) {
        if (cardNumber == null) {
            throw new RuntimeException("未找到会员卡");
        }
        // 消费金额大于0，把消费金额设置为负数
        if (BigDecimal.ZERO.compareTo(amount) <= 0) {
            amount = BigDecimal.ZERO.subtract(amount);
        }
        CardExpenseRecordEntity recordEntity = buildCardExpenseRecordEntity(cardNumber, amount);

//        recordEntity.setType(type.getType());
//        recordEntity.setName(remarks);
//        recordEntity.setFlowType(true);

        switch (type) {
            case deposit:
                // 押金
            case accommodation:
                // 住宿
                // 这两个允许透支金额
                break;
            default:
                // 其余类型无法透支金额
                if (BigDecimal.ZERO.compareTo(cardNumber.getBalance()) > 0) {
                    throw new RuntimeException("余额不足，无法继续消费");
                }
        }

        save(recordEntity);
        cardNumberService.updateById(cardNumber);
    }
//
//    @Override
//    public PrintReceiptVO getPrintReceiptInfo(List<String> ids) {
//        List<CardExpenseRecordEntity> list;
//        if (ids.isEmpty()) {
//            list = new ArrayList<>();
//        } else {
//            list = lambdaQuery().in(CardExpenseRecordEntity::getId, ids).list();
//        }
//        Set<String> collect = list.stream().map(CardExpenseRecordEntity::getMemberCard).collect(Collectors.toSet());
//        if (collect.size() != 1) {
//            throw new RuntimeException("请只选择一个人的消费记录");
//        }
//        OldmanInfoEntity oldmanInfoEntity = oldmanInfoService.lambdaQuery().eq(OldmanInfoEntity::getMemberCard, list.get(0).getMemberCard()).one();
//        if (oldmanInfoEntity == null) {
//            throw new RuntimeException("找不到该消费记录关联的老人信息");
//        }
//        // 获得老人的床位信息
//        BedInfoVO bedInfoVO = bedManagementService.getOldmanBed(oldmanInfoEntity.getId());
//        PrintReceiptVO vo = new PrintReceiptVO();
//        vo.setOldmanName(oldmanInfoEntity.getOldmanName());
//        vo.setUserName(UserUtils.getUser().getNickname());
//        vo.setOldmanBed(bedInfoVO);
//        // 生成打印时所需要的打印明细
//        List<PrintReceiptVO.PrintReceiptRecordVO> recordVOList = list.stream().map(item -> {
//            PrintReceiptVO.PrintReceiptRecordVO recordVO = new PrintReceiptVO.PrintReceiptRecordVO();
//            recordVO.setId(item.getId());
//            recordVO.setAmount(item.getAmount());
//            recordVO.setType(item.getPayServiceId());
//            recordVO.setRemarks(item.getServiceType());
//            recordVO.setStatus("收费");
//            return recordVO;
//        }).collect(Collectors.toList());
//        // 记录合计金额
////        BigDecimal bigDecimal = recordVOList.stream().map(PrintReceiptVO.PrintReceiptRecordVO::getAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
////        PrintReceiptVO.PrintReceiptRecordVO recordVO = new PrintReceiptVO.PrintReceiptRecordVO();
////        recordVO.setId("");
////        recordVO.setAmount(bigDecimal);
////        recordVO.setStatus("合计");
////        recordVOList.add(recordVO);
//        vo.setList(recordVOList);
//        return vo;
//    }
}
